#!/usr/bin/python2.7
"Decodes Blowfish encrypted request sent by Kronos bot to the CnC"

__AUTHOR__ = 'hasherezade'

import argparse
import hashlib
from Crypto.Cipher import Blowfish       

def expand_key(key, dest_len):
    while len(key) < dest_len:
        key = key + key
    return key[:dest_len]

def derive_key(bot_id, key_len):
    buf_hash = hashlib.md5(bot_id).hexdigest()
    return expand_key(buf_hash, key_len)

def blowfish_decrypt(enc, key):
    cipher = Blowfish.new(key, Blowfish.MODE_ECB)
    return cipher.decrypt(enc)

def dump_to_file(filename, data):
    with open(filename, 'wb') as f:
        f.write(data)

def main():
    parser = argparse.ArgumentParser(description="Kronos request decoder (a=0, a=2)")
    parser.add_argument('--datafile',dest="datafile",default=None,help="File with the request data (i.e. connect.php?a=0 or connect?a=2)", required=True)
    parser.add_argument('--outfile',dest="outfile",default="out.bin", help="Where to dump the output", required=False)
    parser.add_argument('--botid',dest="bot_id", help="The BotId", required=True)
    args = parser.parse_args()

    key = derive_key(args.bot_id, 56)
    print key

    data = open(args.datafile, 'rb').read()
    data = data[74:]
    data_len = len(data)

    output = blowfish_decrypt(data, key)
    print len(output)

    if output is None:
        print "Output is empty"
        return

    if args.outfile is not None:
        dump_to_file(args.outfile, output)
        print "Dumped decoded to: %s" % (args.outfile)
    else:
        print output
        return

if __name__ == '__main__':
    main()
